package com.example.canal.strategy.config;

import com.example.canal.common.annotation.DbChangeAnalyse;
import com.example.canal.strategy.service.AbstractDBChangeService;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author LiYuhang
 * @version 0.1
 * @application
 * @Date 2021/8/8 21:57
 */
@Component
public final class DbChangeProcessor implements ApplicationContextAware {

    private static ApplicationContext context;

    private final Class dbChangeServiceClass = AbstractDBChangeService.class;

    private static final ConcurrentHashMap<String, Class<? extends AbstractDBChangeService>> STRATEGY_MAP = new ConcurrentHashMap<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
        Map<String, Object> beans = applicationContext.getBeansWithAnnotation(DbChangeAnalyse.class);
        for (Map.Entry<String, Object> entry : beans.entrySet()) {
            Class<AbstractDBChangeService> aClass = (Class<AbstractDBChangeService>) entry.getValue().getClass();
            if(dbChangeServiceClass.isAssignableFrom(aClass)){
                DbChangeAnalyse annotation = aClass.getAnnotation(DbChangeAnalyse.class);
                STRATEGY_MAP.put(annotation.tableName().toLowerCase(),aClass);
            }
        }
    }

    public static AbstractDBChangeService getDBChangeService(String tableName) {
        Class<? extends AbstractDBChangeService> aClass = STRATEGY_MAP.get(tableName);
        if (aClass != null) {
            return context.getBean(aClass);
        }
        return null;
    }


}
